<html>
<head>
<meta charset="UTF-8">

<!-----------------------------------------------------------------------------
-- Spine Runtimes Software License
-- Version 2.3
-- 
-- Copyright (c) 2013-2015, Esoteric Software
-- All rights reserved.
-- 
-- You are granted a perpetual, non-exclusive, non-sublicensable and
-- non-transferable license to use, install, execute and perform the Spine
-- Runtimes Software (the "Software") and derivative works solely for personal
-- or internal use. Without the written permission of Esoteric Software (see
-- Section 2 of the Spine Software License Agreement), you may not (a) modify,
-- translate, adapt or otherwise create derivative works, improvements of the
-- Software or develop new applications using the Software or (b) remove,
-- delete, alter or obscure any trademarks or any copyright, trademark, patent
-- or other intellectual property or proprietary rights notices on or in the
-- Software, including any copy thereof. Redistributions in binary or source
-- form must include this license and terms.
-- 
-- THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-- EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------>

<title>spine-turbulenz</title>
<script src="../spine-js/spine.js"></script>
<script src="../turbulenz/turbulenzengine.js"></script>
<script src="../turbulenz/graphicsdevice.js"></script>
<script src="../turbulenz/draw2d.js"></script>
<script src="../SpriteBatch.js"></script>
<style>body, input { font-family: tahoma; font-size: 11pt }</style>
</head>
<body>

<div id="message"></div>
<div><canvas id="canvas" width="640" height="480"/></div>
<br>
<input type="button" value="Spineboy" onclick="load('spineboy', 0.6)">
<input type="button" value="Hero" onclick="load('hero', 1)">
<input type="button" value="Goblins" onclick="load('goblins', 1)">
 &nbsp; &nbsp; Click to change the animation or skin.

<script>
var canvas = document.getElementById("canvas");
var TurbulenzEngine = WebGLTurbulenzEngine.create({canvas: canvas});
var graphicsDevice = TurbulenzEngine.createGraphicsDevice({});
var draw2D = Draw2D.create({graphicsDevice: graphicsDevice});

load("spineboy", 0.6);
//load("hero", 1);
//load("goblins", 1);

var atlas;
var skeletonData;
var skeletonName;
function load (name, scale) {
	skeletonName = name;
	TurbulenzEngine.request("data/" + skeletonName + ".atlas", loadAtlas);

	function loadAtlas (atlasText) {
		var textureCount = 0;
		atlas = new spine.Atlas(atlasText, {
			load: function (page, path, atlas) {
				textureCount++;
				graphicsDevice.createTexture({
					src: "data/" + path,
					mipmaps: true,
					onload: function (texture) {
						page.rendererObject = texture;
						page.width = texture.width;
						page.height = texture.height;
						atlas.updateUVs(page);
						textureCount--;
					}
				});
			},
			unload: function (texture) {
				texture.destroy();
			}
		});

		function waitForTextures () {
			if (!textureCount)
				TurbulenzEngine.request("data/" + skeletonName + ".json", loadSkeletonData);
			else
				setTimeout(waitForTextures, 100);
		}
		waitForTextures();
		
		function loadSkeletonData (skeletonText) {
			var json = new spine.SkeletonJson(new spine.AtlasAttachmentLoader(atlas));
			json.scale = scale;
			skeletonData = json.readSkeletonData(JSON.parse(skeletonText));
			start();
		}
	}
}

function start () {
	spine.Bone.yDown = true;

	var skeleton = new spine.Skeleton(skeletonData);
	skeleton.x = 320;
	skeleton.y = 440;
	skeleton.updateWorldTransform();

	var stateData = new spine.AnimationStateData(skeletonData);	
	var state = new spine.AnimationState(stateData);

	if (skeletonName == "spineboy") {
		stateData.setMixByName("walk", "jump", 0.2);
		stateData.setMixByName("run", "jump", 0.2);
		stateData.setMixByName("jump", "run", 0.2);
		state.setAnimationByName(0, "walk", true);

		canvas.onmousedown = function () {
			state.setAnimationByName(0, "jump", false);
			state.addAnimationByName(0, "run", true, 0);
		}
	} else if (skeletonName == "hero") {
		stateData.defaultMix = 0.2;
		stateData.setMixByName("Walk", "Attack", 0);
		stateData.setMixByName("Attack", "Run", 0);
		stateData.setMixByName("Run", "Attack", 0);
		state.setAnimationByName(0, "Idle", true);

		canvas.onmousedown = function () {
			var name = state.getCurrent(0).animation.name;
			if (name == "Idle") {
				state.setAnimationByName(0, "Crouch", true);
			} else if (name == "Crouch") {
				state.setAnimationByName(0, "Walk", true);
			} else {
				state.setAnimationByName(0, "Attack", false);
				state.addAnimationByName(0, "Run", true, 0);
			}
		}
	} else {
		skeleton.setSkinByName("goblingirl");
		skeleton.setSlotsToSetupPose();
		state.setAnimationByName(0, "walk", true);

		canvas.onmousedown = function () {
			skeleton.setSkinByName(skeleton.skin.name == "goblin" ? "goblingirl" : "goblin");
			skeleton.setSlotsToSetupPose();
		}
	}
	
	state.onEvent = function (trackIndex, event) {
		// alert(trackIndex + " event: " + event.data.name)
	}

	var bgColor = [0.9, 0.9, 0.9, 1.0];
	var batch = new SpriteBatch(draw2D);
	var lastTime = TurbulenzEngine.time;
	function update() {
		if (!graphicsDevice) return;

		var delta = TurbulenzEngine.time - lastTime;
		lastTime = TurbulenzEngine.time;
		state.update(delta);
		state.apply(skeleton);
		skeleton.updateWorldTransform();

		graphicsDevice.clear(bgColor, 1.0);
		batch.begin(draw2D.blend.alpha);
		drawSkeleton(batch, skeleton);
		batch.end();
		graphicsDevice.endFrame();
	}

	TurbulenzEngine.setInterval(update, 1000 / 60);
}

var vertices = [];
function drawSkeleton (batch, skeleton) {
	var drawOrder = skeleton.drawOrder;
	for (var i = 0, n = drawOrder.length; i < n; i++) {
		var slot = drawOrder[i];
		var attachment = slot.attachment;
		if (!(attachment instanceof spine.RegionAttachment)) continue;
		attachment.computeVertices(skeleton.x, skeleton.y, slot.bone, vertices);
		
		var blendMode = slot.data.blendMode == spine.BlendMode.additive ? draw2D.blend.additive : draw2D.blend.alpha;
		if (batch.blendMode != blendMode) {
			batch.end();
			batch.begin(blendMode);
		}

		batch.add(
			attachment.rendererObject.page.rendererObject,
			vertices[0], vertices[1],
			vertices[6], vertices[7],
			vertices[2], vertices[3],
			vertices[4], vertices[5],
			skeleton.r * slot.r,
			skeleton.g * slot.g,
			skeleton.b * slot.b,
			skeleton.a * slot.a,
			attachment.uvs[0], attachment.uvs[1],
			attachment.uvs[4], attachment.uvs[5]
		);
	}
}
</script>

</body>
</html>